package de.dqi.pong.graphics;

import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.*;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import javax.swing.*;

/**
 * TODO FontHelper - finish class definition
 * <hr>
 * 
 * <hr><dl><dt>
 * Summary: </dt><br><dd>
 *  Allows to create and save font Files for later use.
 * </dd><br><dt>
 * Author: </dt><br><dd>
 *  Vincent
 * </dd></dl>
 */
public class FontHelper
		extends JFrame
		implements ActionListener, InputMethodListener {
	
	public static void main(String[] args) {
		new FontHelper();
	}
	
	private int			tileSize	= 80;
	private int			xTiles		= 4;
	private int			yTiles		= 6;
	private int			fontLetter	= 0;
	
	private JTextField	code;
	private JTextField	letter;
	private JTextField	result;
	private FontTile[]	tiles;
	private JButton		reset;
	private JButton		save;
	
	private int			fontSize	= xTiles * yTiles;
	private int			fontBytes	= fontSize % 8 == 0 ? fontSize / 8 : fontSize / 8 + 1;
	private ByteBuffer	fontData	= ByteBuffer.allocate(2 + fontBytes * 256);
	
	private FontHelper() {
		this.setResizable(false);
		this.setName("PONG Font");
		this.setTitle("PONG Font");
		this.setSize(tileSize * xTiles, 20 + 3 * tileSize + tileSize * yTiles);
		this.setLayout(null);
		
		code = new JTextField();
		code.setLocation(0, 0);
		code.setSize(xTiles * tileSize / 2, tileSize);
		code.setText("Code");
		code.setHorizontalAlignment(SwingConstants.CENTER);
		code.setToolTipText("ID");
		code.addInputMethodListener(this);
		this.add(code);
		
		letter = new JTextField();
		letter.setLocation(xTiles * tileSize / 2, 0);
		letter.setSize(xTiles * tileSize / 2, tileSize);
		letter.setText("Char");
		letter.setHorizontalAlignment(SwingConstants.CENTER);
		letter.setToolTipText("Character");
		letter.addInputMethodListener(this);
		this.add(letter);
		
		Container grid = new Container();
		grid.setLocation(0, tileSize);
		grid.setSize(xTiles * tileSize, yTiles * tileSize);
		grid.setLayout(new GridLayout(0, xTiles));
		tiles = new FontTile[xTiles * yTiles];
		for (int i = 0; i < xTiles * yTiles; i++) {
			FontTile tile = new FontTile(i, this);
			grid.add(tile);
			tiles[i] = tile;
		}
		this.add(grid);
		
		result = new JTextField();
		result.setLocation(0, tileSize + tileSize * yTiles);
		result.setSize(xTiles * tileSize, tileSize);
		result.setText(Integer.toString(fontLetter));
		result.setEditable(false);
		result.setHorizontalAlignment(SwingConstants.CENTER);
		result.setToolTipText(Integer.toBinaryString(fontLetter));
		this.add(result);
		
		reset = new JButton();
		reset.setLocation(0, 2 * tileSize + tileSize * yTiles);
		reset.setSize(xTiles * tileSize / 2, tileSize);
		reset.setText("clear");
		reset.setHorizontalAlignment(SwingConstants.CENTER);
		reset.addActionListener(this);
		this.add(reset);
		
		save = new JButton();
		save.setLocation(xTiles * tileSize / 2, 2 * tileSize + tileSize * yTiles);
		save.setSize(xTiles * tileSize / 2, tileSize);
		save.setText("save");
		save.setHorizontalAlignment(SwingConstants.CENTER);
		save.addActionListener(this);
		this.add(save);
		
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		this.setVisible(true);
	}
	
	private void saveFont() {
		try (RandomAccessFile aFile = new RandomAccessFile("data/" + Integer.toString(xTiles) + "x"
				+ Integer.toString(yTiles) + ".font", "w");
				FileChannel outChannel = aFile.getChannel())
		{
			fontData.rewind();
			outChannel.write(fontData);
			fontData.flip();
			outChannel.close();
			aFile.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == reset) {
			clearTiles();
		} else {
			toggleTile((FontTile) e.getSource());
		}
		
		updateResult();
	}
	
	private void updateResult() {
		result.setText(Integer.toString(fontLetter));
		result.setToolTipText(Integer.toBinaryString(fontLetter));
	}
	
	private void clearTiles() {
		for (int i = 0; i < xTiles * yTiles; i++) {
			tiles[i].setBackground(java.awt.Color.WHITE);
			tiles[i].marked = false;
		}
		fontLetter = 0;
	}
	
	private void toggleTile(FontTile tile) {
		if (tile.marked) {
			tile.setBackground(java.awt.Color.WHITE);
			tile.marked = false;
		} else {
			tile.setBackground(java.awt.Color.BLACK);
			tile.marked = true;
		}
		changeFont(tile.index, tile.marked);
	}
	
	private void changeFont(int index, boolean set) {
		if (set) {
			int bitmask = 1 << index;
			fontLetter = fontLetter | bitmask;
		} else {
			int bitmask = (-1) ^ (1 << index);
			fontLetter = fontLetter & bitmask;
		}
		
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.event.InputMethodListener#caretPositionChanged(java.awt.event.InputMethodEvent)
	 */
	@Override
	public void caretPositionChanged(InputMethodEvent event) {
		System.out.println("Caret");
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * java.awt.event.InputMethodListener#inputMethodTextChanged(java.awt.event.InputMethodEvent)
	 */
	@Override
	public void inputMethodTextChanged(InputMethodEvent event) {
		System.out.println("Text");
	}
	
}
